﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TiposComuns.Objectos
{
    /// <summary>
    /// Interface for the user to interact with it's servers
    /// </summary>
    public interface IServer
    {
        #region Init
        /// <summary>
        /// Connects to the primary server. The primary is chosen by the user.
        /// </summary>
        /// <param name="username">Username</param>
        /// <returns>Global state of the servers</returns>
        State Connect(string username);

        /// <summary>
        /// Returns the server's state
        /// </summary>
        /// <returns>State</returns>
        State GetState();
        #endregion

        #region Profile
        /// <summary>
        /// Obtains the user's profile
        /// </summary>
        /// <returns>User's profile</returns>
        Profile GetProfile();

        /// <summary>
        /// Sets the user's profile
        /// </summary>
        /// <param name="profile">User's new profile</param>
        State SetProfile(IDMsg id, Profile profile);
        #endregion

        #region Posts
        /// <summary>
        /// Post a new message on the wall
        /// </summary>
        /// <param name="post">New post</param>
        State Post(Post post);

        /// <summary>
        /// Returns user's posts
        /// </summary>
        /// <returns>List of posts</returns>
        List<Post> GetPosts();

        /// <summary>
        /// Return the most recent posts from all friend's wall
        /// </summary>
        /// <returns>List of new posts</returns>
        KeyValuePair<State, List<Post>> RefreshWall();

        #endregion

        #region Friends
        /// <summary>
        /// Sends a request to a remote user
        /// </summary>
        /// <param name="id">Identifier of the message</param>
        /// <param name="target">Target of the request</param>
        State FriendRequest(IDMsg id, Person target);


        /// <summary>
        /// Accepts a user as a friend
        /// </summary>
        /// <param name="id">Identifier of the message</param>
        /// <param name="target">New friend</param>
        State FriendAccept(IDMsg id, Person target);

        /// <summary>
        /// Rejects a friendship request
        /// </summary>
        /// <param name="id">Identifier of the message</param>
        /// <param name="target">Person who sent the request</param>
        State FriendReject(IDMsg id, Person target);

        /// <summary>
        /// Removes a friend
        /// </summary>
        /// <param name="id">Identifier of the message</param>
        /// <param name="target">Friend who one wants to be removed</param>
        State FriendRemove(IDMsg id, Person target);

        

        /// <summary>
        /// Returns the list of friends
        /// </summary>
        /// <returns>List of friends</returns>
        List<Person> GetFriends();

        List<Person> GetFriendsReceived();

        List<Person> GetFriendsSent();

        #endregion

        #region Search

        /// <summary>
        /// Performs a search by the username
        /// </summary>
        /// <param name="username">Searched username</param>
        void StartLookupUsername(string username);

        /// <summary>
        /// Starts a lookup by users that have a particular interest
        /// </summary>
        /// <param name="interest">Interest</param>
        void StartLookup(string interest);

        /// <summary>
        /// Starts a lookup by users that have an age placed between two values, and a particular sex
        /// </summary>
        ///<param name="ageMax">Upper bound for the age</param>
        ///<param name="ageMin">Lower bound for the age</param>
        ///<param name="sex">Sex(true means male, false means female)</param>
        void StartLookup(int ageMin,int ageMax,bool sex);

        /// <summary>
        /// Obtains the available results of the last conducted search
        /// </summary>
        /// <returns>Available results and a bool that indicates if we should continue the search</returns>
        KeyValuePair<List<Person>,bool> GetResults();
        #endregion

        State ChangeServer();

        Address GetAddress();
    }
}
